/**
 * Created by meiguizhinian on 2018/7/20
 * Copyright © 2018 lixiaolong. All rights reserved.
 */

//cocos2dx class
ivy.UIJoyStick = ivy.UIBase.extend({
	ctor: function (formName, blockName, sourceControlData) {
		this._super();

		if (formName && blockName && sourceControlData) {
			this.initWith(formName, blockName, sourceControlData);
		}
	},

	// initWith : function(formName, blockName, sourceControlData);
	// initWith(int32_t formID,int32_t blockID, TouchMode touchMode = TouchMode::eMulitTouch);
	initWith : function() {
		if (cc.isNumber(arguments[0])) {
			let formID = arguments[0];
			let blockID = arguments[1];
			let touchMode = arguments.length>2? arguments[2]:ivy.UIBase.TouchMode.eMulitTouch;

			this._touchMode = touchMode;
			let uim = ivy.UIManager.getInstance();
			let aniIDInUI = uim.getBlockDataByType(formID, blockID, ivy.UIManager.FormDataType.eBgAniID);
			let actionIDInUI = uim.getBlockDataByType(formID, blockID, ivy.UIManager.FormDataType.eBgActionID);
			let seqIDInUI = uim.getBlockDataByType(formID, blockID, ivy.UIManager.FormDataType.eBgSeqID);
			let aniFileName = uim.getAniFileNameByUIAniID(aniIDInUI);
			this._backSprite = ivy.AniPlayer.create(aniFileName, actionIDInUI, seqIDInUI === -1 ? 0 : seqIDInUI, true, seqIDInUI === -1 ? ivy.AniPlayState.ePause : ivy.AniPlayState.eCircle);
			this.addChild(this._backSprite);

			aniIDInUI = uim.getBlockDataByType(formID, blockID, ivy.UIManager.FormDataType.eSelBgAniID);
			actionIDInUI = uim.getBlockDataByType(formID, blockID, ivy.UIManager.FormDataType.eSelBgActionID);
			seqIDInUI = uim.getBlockDataByType(formID, blockID, ivy.UIManager.FormDataType.eSelBgSeqID);
			aniFileName = uim.getAniFileNameByUIAniID(aniIDInUI);
			this._midSprite = ivy.AniPlayer.create(aniFileName, actionIDInUI, seqIDInUI === -1 ? 0 : seqIDInUI, true, seqIDInUI === -1 ? ivy.AniPlayState.ePause : ivy.AniPlayState.eCircle);
			this.addChild(this._midSprite);

			let x = uim.getBlockDataByType(formID, blockID, ivy.UIManager.FormDataType.ePosX);
			let y = uim.getBlockDataByType(formID, blockID, ivy.UIManager.FormDataType.ePosY);
			let w = uim.getBlockDataByType(formID, blockID, ivy.UIManager.FormDataType.eWidth);
			let h = uim.getBlockDataByType(formID, blockID, ivy.UIManager.FormDataType.eHeight);
			this.setSrcRect(cc.rect(x, y, w, h));

			this._centerPoint = ivy.Tools.ConvertPointToGL(cc.p(x+w/2,y+h/2));
			this._touchRadius = w / 2.0;
			this._actived = false;
			this._curTouchPoint = cc.p(this._centerPoint);
			this._backSprite.setPosition(this._centerPoint);
			this._midSprite.setPosition(this._centerPoint);
			this.active();//激活摇杆
			this.schedule(this.update,0.05);
			this.setCascadeColorAndOpacityEnabled(true);
			this.setContentSize(cc.size(this._touchRadius*2.0, this._touchRadius*2.0));
		} else {
			let formName = arguments[0];
			let blockName = arguments[1];
			let sourceControlData = arguments[2];

			let uim = ivy.UIManager.getInstance();
			this.setCascadeColorAndOpacityEnabled(true);
			let aniIDInUI = uim.getBlockDataByType(formName, blockName, ivy.UIManager.FormDataType.eBgAniID);
			let actionIDInUI = uim.getBlockDataByType(formName, blockName, ivy.UIManager.FormDataType.eBgActionID);
			let seqIDInUI = uim.getBlockDataByType(formName, blockName, ivy.UIManager.FormDataType.eBgSeqID);
			let aniIDInUISel = uim.getBlockDataByType(formName, blockName, ivy.UIManager.FormDataType.eSelBgAniID);
			let actionIDInUISel = uim.getBlockDataByType(formName, blockName, ivy.UIManager.FormDataType.eSelBgActionID);
			let seqIDInUISel = uim.getBlockDataByType(formName, blockName, ivy.UIManager.FormDataType.eSelBgSeqID);
			let x = uim.getBlockDataByType(formName, blockName, ivy.UIManager.FormDataType.ePosX);
			let y = uim.getBlockDataByType(formName, blockName, ivy.UIManager.FormDataType.ePosY);
			let w = uim.getBlockDataByType(formName, blockName, ivy.UIManager.FormDataType.eWidth);
			let h = uim.getBlockDataByType(formName, blockName, ivy.UIManager.FormDataType.eHeight);
			let layerID = uim.getBlockDataByType(formName, blockName, ivy.UIManager.FormDataType.eLayerID);
			this._layerIDInEditor = layerID;

			let aniFileName = uim.getAniFileNameByUIAniID(aniIDInUI);
			this._backSprite = ivy.AniPlayer.create(aniFileName, actionIDInUI, seqIDInUI === -1 ? 0 : seqIDInUI, true, seqIDInUI === -1 ? ivy.AniPlayState.ePause : ivy.AniPlayState.eCircle);
			this.addChild(this._backSprite);

			aniFileName = uim.getAniFileNameByUIAniID(aniIDInUISel);
			this._midSprite = ivy.AniPlayer.create(aniFileName, actionIDInUISel, seqIDInUISel === -1 ? 0 : seqIDInUISel, true, seqIDInUISel === -1 ? ivy.AniPlayState.ePause : ivy.AniPlayState.eCircle);
			this.addChild(this._midSprite);

			this.setSrcRect(cc.rect(x, y, w, h));
			this._centerPoint = ivy.Tools.ConvertPointToGL(cc.p(x + w / 2, y + h / 2));
			this._touchRadius = w/2.0;
			this._actived = false;
			this._curTouchPoint = cc.p(this._centerPoint);
			this._backSprite.setPosition(this._centerPoint);
			this._midSprite.setPosition(this._centerPoint);
			this.active();//激活摇杆
			this.scheduleUpdate();
			this.setCascadeColorAndOpacityEnabled(true);
			this.setContentSize(cc.size(this._touchRadius*2.0, this._touchRadius*2.0));
			this._enterActionID.setValue(uim.getControlActionDataByFindIndex(sourceControlData.propertyDataFindIndex[ivy.DefaultSourceControlTypes.SCT_ELEMENT_JoyStick_EnterAction_action]));
			this._outActionID.setValue(uim.getControlActionDataByFindIndex(sourceControlData.propertyDataFindIndex[ivy.DefaultSourceControlTypes.SCT_ELEMENT_JoyStick_OutAction_action]));
			this._bindJoyIndex= uim.getControlIntDataByFindIndex(sourceControlData.propertyDataFindIndex[ivy.DefaultSourceControlTypes.SCT_ELEMENT_JoyStick_BindJoyStickIndex_int]);
			this.setUIElementName(formName, blockName);
			if (this._bindJoyIndex>=0) {
				let index = this._bindJoyIndex;

				this.setTouchDoubleCallback(function(base) {
					ivy.ControlManager.getInstance().setJoyState(index, ivy.ControlManager.ControlState.eTouchDouble, true, base.getDegree(), base.getStrength());
				});

				this.setTouchEnterCallback(function(base){
					let cm = ivy.ControlManager.getInstance();
					let degree = joy.getDegree();
					let str = joy.getStrength();
					cm.setJoyState(index, ivy.ControlManager.ControlState.eTouchEnter, true, degree, str);
					cm.setJoyState(index, ivy.ControlManager.ControlState.eTouching, true, degree, str);
				});
				this.setTouchingCallback(function(base){
					ivy.ControlManager.getInstance().setJoyState(index, ivy.ControlManager.ControlState.eTouching, true, base.getDegree(), base.getStrength());
				});
				this.setTouchEndCallback(function(base){
					let cm = ivy.ControlManager.getInstance();
					let degree = base.getDegree();
					let str = base.getStrength();

					ivy.ControlManager.getInstance().setJoyState(index, ivy.ControlManager.ControlState.eTouching, false);
					ivy.ControlManager.getInstance().setJoyState(index, ivy.ControlManager.ControlState.eTouchEnd, true, base.getDegree(), base.getStrength());
				});
			}
		}
	},

	active : function() {
		if (!this._actived) {
			this._curTouchID = this._invaildTouchID;
			this._actived = true;
			this._lifeTimer = 0;

			//添加触摸回调 根据isEnableMultiTouch_ 来决定是否为多点触摸
			let listener1 = {};
			if (this._touchMode === ivy.UIBase.TouchMode.eMulitTouch) {
				listener1.event = cc.EventListener.TOUCH_ALL_AT_ONCE;
				listener1.onTouchesBegan = this.onTouchesBegan.bind(this);
				listener1.onTouchesMoved = this.onTouchesMoved.bind(this);
				listener1.onTouchesEnded = this.onTouchesEnded.bind(this);
			} else {
				listener1.event = cc.EventListener.TOUCH_ONE_BY_ONE;
				listener1.swallowTouches = true;
				listener1.onTouchBegan = this.onTouchBegan.bind(this);
				listener1.onTouchMoved = this.onTouchMoved.bind(this);
				listener1.onTouchEnded = this.onTouchEnded.bind(this);
			}
			this._multiTouchListener = cc.EventListener.create(listener1);
			cc.eventManager.addListener(this._multiTouchListener, this);
		}
	},
	inActive : function() {
		if (this._actived) {
			this._actived = false;
			this.unschedule(this.update);
			if (this.touchListener_) {
				cc.eventManager.removeEventListener(this.touchListener_);
				this.touchListener_ = null;
			}
			if (this._multiTouchListener) {
				cc.eventManager.removeEventListener(this._multiTouchListener);
				this._multiTouchListener = null;
			}
		}
	},
	update : function(dt) {
		++this._lifeTimer;
		this._midSprite.setPosition(cc.pAdd(this._midSprite.getPosition(), cc.pMult(cc.pSub(this._curTouchPoint, this._midSprite.getPosition()), 0.5)));
		if (this._isTouching&&this._touchingFunc) {
			this._touchingFunc(this);
		}
	},
	//获取摇杆中心图标节点
	getMidNode : function() {
		return this._midSprite;
	},
	//获取摇杆底图节点
	getBackNode : function() {
		return this._backSprite;
	},
	//获取当前摇杆触摸角度(正上方0度正下方180度正右方90度)
	getDegree : function() {
		return ivy.Tools.getPointsDegree(this._curTouchPoint, this._centerPoint);
	},
	//获取当前摇杆触摸方向向量(已归一化)
	getDirection : function() {
		let p = cc.pSub(this._curTouchPoint, this._centerPoint);
		cc.pNormalizeIn(p);
		return p;
	},
	//获取当前摇杆触摸强度(即触摸点和中心点偏移0-100)
	getStrength : function() {
		return Math.ceil(100*cc.pDistanceSQ(this._centerPoint, this._curTouchPoint) / (this._touchRadius*this._touchRadius));
	},
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////protected:
	_curTouchID : 0,
	_invaildTouchID : -1,
	_touchRadius : 0.0,
	_actived : false,
	_isTouching : false,
	_curTouchPoint : null,//cc.p
	_centerPoint : null,//cc.p
	_size : null,//cc.size
	_touchMode : ivy.UIBase.TouchMode.eMulitTouch,
	_backSprite : null,//cc::AniPlayer*
	_midSprite : null,//cc::AniPlayer*

	onTouchBegan : function(touch, event) {
		if (!this._actived)
			return false;

		let touchPoint = touch.getLocationInView();
		touchPoint = cc.director.convertToGL(touchPoint);

		if (cc.pDistanceSQ(touchPoint, this._centerPoint) > this._touchRadius*this._touchRadius) {
			return false;
		}
		this._isTouching = true;
		this._curTouchPoint = touchPoint;
		if (this._touchEnterFunc)
			this._touchEnterFunc(this);
		if (this._touchDoubleFunc) {
			if (this._checkDoubleTouch) {
				this._doubleTouchTimer = this._lifeTimer;
				this._checkDoubleTouch = false;
			} else {
				let curLifeTimer = this._lifeTimer;
				if (curLifeTimer - this._doubleTouchTimer < 20) {
					if (this._touchDoubleFunc)
						this._touchDoubleFunc(this);
					this._checkDoubleTouch = true;
				} else {
					this._doubleTouchTimer = this._lifeTimer;
				}
			}
		}
		return true;
	},
	onTouchMoved : function(touch, event) {
		let touchPoint = touch.getLocationInView();
		touchPoint = cc.director.convertToGL(touchPoint);
		if (cc.pDistanceSQ(touchPoint, this._centerPoint) > this._touchRadius*this._touchRadius) {
			let sub = cc.pSub(touchPoint, this._centerPoint);
			cc.pNormalizeIn(sub);
			this._curTouchPoint = cc.pAdd(this._centerPoint , cc.pMult(sub, this._touchRadius));
		} else {
			this._curTouchPoint = touchPoint;
		}
	},
	onTouchEnded : function(touch, event) {
		this._curTouchPoint = this._centerPoint;
		this._isTouching = false;
		if (this._touchEndFunc)
			this._touchEndFunc(this);
	},

	onTouchesBegan : function(touches, event) {
		if (!this._actived)
			return;
		for (let item of touches) {
			let touch = item;
			let target = this;
			let locationInNode = target.convertToNodeSpace(touch.getLocation());
			let s = target.getContentSize();
			let rect = cc.rect(0, 0, s.width, s.height);

			if (cc.rectContainsPoint(rect, locationInNode) && this._curTouchID === this._invaildTouchID) {
				let touchPoint = touch.getLocationInView();
				touchPoint = cc.director.convertToGL(touchPoint);
				this._curTouchID = item.getID();
				this._isTouching = true;
				this.setVisible(true);
				this._curTouchPoint = touchPoint;
				if (this._touchEnterFunc)
					this._touchEnterFunc(this);
				if (this._touchDoubleFunc) {
					if (this._checkDoubleTouch) {
						this._doubleTouchTimer = this._lifeTimer;
						this._checkDoubleTouch = false;
					} else {
						let curLifeTimer = this._lifeTimer;
						if (curLifeTimer - this._doubleTouchTimer < 16) {
							if (this._touchDoubleFunc)
								this._touchDoubleFunc(this);
							this._checkDoubleTouch = true;
						} else {
							this._doubleTouchTimer = this._lifeTimer;
						}
					}
				}
				return;
			}
		}
	},
	onTouchesMoved : function(touches, event) {
		for (let item of touches) {
			if (item.getID() === this._curTouchID && this._isTouching) {
				let touchPoint = item.getLocationInView();
				touchPoint = cc.director.convertToGL(touchPoint);
				if (cc.pDistanceSQ(touchPoint, this._centerPoint) > this._touchRadius*this._touchRadius) {
					let sub = cc.pSub(touchPoint, this._centerPoint);
					cc.pNormalizeIn(sub);
					this._curTouchPoint = cc.pAdd(this._centerPoint , cc.pMult(sub, this._touchRadius));
				} else {
					this._curTouchPoint = touchPoint;
				}
				return;
			}
		}
	},
	onTouchesEnded : function(touches, event) {
		for (let item of touches) {
			if (item.getID() === this._curTouchID) {
				if (this._touchEndFunc)
					this._touchEndFunc(this);
				this._curTouchID = this._invaildTouchID;
				this._curTouchPoint = this._centerPoint;
				this._isTouching = false;
			}
		}
	},

	_multiTouchListener : null,
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////private:
	//用于检测双击
	_lifeTimer : 0,
	_doubleTouchTimer : 0,
	_checkDoubleTouch : true,
	_bindJoyIndex : -1,
});

ivy.UIJoyStick.create = function (formName, blockName, sourceControlData) {
	return new ivy.UIJoyStick(formName, blockName, sourceControlData);
};
